/* 
    <provides OS-like functionality using a time-triggered scheduler>
    Copyright (C) <2012>  <Jonathan D. Armstrong> <jonathan.armstrong AT mavs.uta.edu>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file   state-machine.c
 * @Author Jonathan D. Armstrong (jonathan.armstrong@mavs.uta.edu)
 * @date   December, 2012
 * @brief  Brief description of file.
 *
 * Detailed description of file.
 */

#include <stdint.h>
#include <stdio.h>
#include "state-machine.h"
#include "projectdefs.h"

/* maximum number of states for this particular task */
const uint8_t maxStates = (STATE3 - STATE1) + 1;
#define MAX_STATES (STATE3-STATE1)+1

/* initialize table to link states with associated functions */
state_table_t state[MAX_STATES] = {{STATE1, &state1_function},
                                   {STATE2, &state2_function},
                                   {STATE3, &state3_function}};


/* accepts argument reserved for future use and returns
   state which state machine should be set to next time thru the task */
state_t state1_function(uint8_t arg)
{
    /* do something */
    printf("state1_function(%u)\r\n", arg);
    
    /* return state to execute on next possible task execution */
    return STATE2;
}


state_t state2_function(uint8_t arg)
{
    /* do something */
    printf("state2_function(%u)\r\n", arg);
    
    return STATE3;
}


state_t state3_function(uint8_t arg)
{
    /* do something */
    printf("state3_function(%u)\r\n", arg);
    
    return STATE1;
}

/**
 * @name    Lengthy Task
 * @brief   Simply display which state lengthy_task() is in presently.
 *
 * Illustrate use of short duration states to accomplish lengthier task.
 *
 * @param [in] argument  Reserved for possible future use.
 *
 * @retval exit_status   Reserved for possible future use.
 *
 * Example Usage:
 * @code
 *    status = create_task(&lengthy_task, 1, DELAYED); // adds task to the task control block for scheduling
 * @endcode
 */
uint8_t lengthy_task(uint8_t arg)
{
    /* track which state we are currently in */
    static uint8_t stateIndex = 0;
    /* just pass into functions to demonstrate functionality */
    static uint8_t var = 0;
    
    #ifdef TASK_DEBUG
        printf("\r\n");
        printf("length_task(%u)\r\n", arg);
    #endif
    
    /* run function associated with current state */
    stateIndex = state[stateIndex].functionPtr(var);
    
    /* increment so we see value change when printed in each state function */
    var++;
    
    /* reset task to delay */
    delay_task(&lengthy_task);
}